package com.es.www.jdk.factory;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;

import com.es.www.jdk.advice.LogAdvice;
import com.google.common.base.Splitter;

/**
 * @Created by michangtao
 * @Date 2022/1/26 16:24
 * @Description 静态工厂
 */
@Slf4j
public class CustomBeanFactory<T> {

    private String beanName;

    private static Map<String, Object> beanMap = new HashMap<>();

    private static Properties prop;

    public CustomBeanFactory(String beanName) {
        this.beanName = beanName;
    }

    static {
        try {
            prop = new Properties();
            prop.load(CustomBeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static <T> T getBean(String beanName) {
        if (!beanMap.containsKey(beanName)) {
            synchronized (CustomBeanFactory.class) {
                if (!beanMap.containsKey(beanName)) {
                    try {
                        Class<?> beanClass = Class.forName(prop.getProperty(beanName));
                        Object bean = beanClass.newInstance();
                        //实例化bean之后去配置文件中查看需要增强的方法
                        T proxy = proxyBean(beanClass,bean);
                        beanMap.put(beanName, proxy);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return (T) beanMap.get(beanName);
    }

    private static <T> T proxyBean(Class<?> beanClass,Object bean) {
        T proxy;
        Properties properties = new Properties();
        try {
            properties.load(CustomBeanFactory.class.getClassLoader().getResourceAsStream("proxy.properties"));
            String proxyClass = properties.getProperty("proxy.class");
            if (Objects.equals(proxyClass,beanClass.getName())) {
                //获取要增强的方法列表
                List<String> methods = Splitter.on(",").omitEmptyStrings().splitToList(properties.getProperty("proxy.method"));

                //为beanClass创建动态代理
                InvocationHandler handler = new LogAdvice(bean,methods);

//                InvocationHandler handler = new InvocationHandler() {
//                    @Override
//                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
////                        log.info("className：{},method：{},args：{}", beanClass, method, args);
//                        System.out.println("啦啦啦");
//                        return method.invoke(bean, args);
//                    }
//                };

                //通过反射创建bean
                proxy = (T) Proxy.newProxyInstance(beanClass.getClassLoader(), beanClass.getInterfaces(), handler);
                return proxy;
            }
            return (T)bean;

        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
